CodePipeline で ECS にデプロイできるようになり、Docker 環境の継続的デリバリも簡単になりました
ども、藤本です。
現地時間 2017/12/12、CodePipeline のデプロイにて、ECS を選択できるようになり、ECS Service にデプロイできるようになりました。
早速、試してみました。
概要
AWS CodePipeline は AWS や AWS 以外の SaaS を繋ぎ合わせて継続的デリバリを実現、モニタリングするサービスです。今まで CodePipeline が連携可能なデプロイサービスには CodeDeploy、Beanstalk、CloudFormation、OpsWorks の 4つがありました。ここに ECS が加わりました。ECS へのデプロイには、今までの EC2 上のコンテナにも可能ですし、先日の re:Invent 2017 で発表された AWS Fargate にも可能です。
今まで CodePipeline を利用して、ECS 環境を継続的デリバリできました。CodeBuild でスクリプトを自前で書くか、CloudFormation を利用する必要がありました。それが今回のアップデートにより、デプロイ先に ECS を指定するだけになったのでより簡単、シンプルになりました。
イメージとしては以下のような感じです。
ちょっとごちゃごちゃ書きましたが、CodePipeline のデプロイ先に ECS クラスタ、サービスを指定するだけで新しい Docker イメージからコンテナをローリングアップデートできます!
試してみた
CodeStar の Python + Django で生成されるウェブアプリケーションをデプロイしてみました。
前提
- ソースコードは CodeStar で生成されるソースコードを流用
- ソースコードリポジトリは CodeCommit を利用
- ECS のクラスタ、サービスは作成済み
↓のような状態。
上の構成図の環境を作っていきましょう。
やること
- buildspec.yml 作成
- CodePipeline のパイプライン作成
- CodeBuild のビルドプロジェクト作成
- デプロイ
- 動作確認
buildspec.yml 作成
上の図にも書いたように CodeBuild でコンテナのビルドや、ECR へのプッシュ、Task Difinitions のファイルを生成します。それら処理を実施するbuildspec.yml
を作成します。ほぼ ECS のドキュメントにあるサンプルをそのまま利用できます。ユニットテストや、コンパイルも実施する場合は別のビルドプロジェクトでやった方が管理しやすいかもしれません。
version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws --version - $(aws ecr get-login --region ${AWS_DEFAULT_REGION}) - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME} - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) build: commands: - echo Build started on `date` - echo Building the Docker image... - docker build -t $REPOSITORY_URI:latest . - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Pushing the Docker images... - docker push $REPOSITORY_URI:latest - docker push $REPOSITORY_URI:$IMAGE_TAG - echo Writing image definitions file... - echo "[{\"name\":\"${IMAGE_NAME}\",\"imageUri\":\"${REPOSITORY_URI}:${IMAGE_TAG}\"}]" > imagedefinitions.json artifacts: files: imagedefinitions.json
AWS_ACCOUNT_ID
、IMAGE_NAME
を別途環境変数で指定します。
CodePipeline のパイプライン作成
CodePipeline の作成と同時に CodeBuild プロジェクトも作成していきましょう。
CodePipeline の画面から Create pipeline で作成を開始します。
Pipeline 名は適当に設定します。
ソースコードリポジトリには CodeCommit を利用します。
ビルドには CodeBuild を利用します。新規プロジェクトを作成します。
Docker イメージを作るのでビルド環境は Docker の Runtime を利用します。Save build project をクリックしてビルドプロジェクトを作成します。
続いて、デプロイです。これが今回のメインでお伝えしたかったアップデートになります。Deployment provider に Amazon ECS が追加されました。
デプロイ先の ECS クラスタ、およびサービスを指定します。Image filename は空白で大丈夫です。その場合、imagedefinitions.json
が利用されます。
CodePipeline が動作する IAM Role を指定します。
設定内容を確認して、作成します。
作成すると、初期デプロイが動作しますが、失敗します。
CodeBuild の環境変数設定
先ほどの buildspec.yml は変数化した変数名をビルドプロジェクトの環境変数に設定します。
CodeBuild のビルドプロジェクトを選択して、Update をクリックします。Environment varables に 2つの環境変数を設定します。
IAM Role への権限付与
CodeBuild 作成時に自動生成した IAM Role には ECR、ECS の権限がありません。Role に Policy を追加します。
デプロイ
これで ECS Service の継続的デリバリの準備が整いました。git push してデプロイを開始しましょう。HTML ファイルのメッセージを変えて、push します。
$ sed -ie 's/You just created a Python Django web application/You just deployed a ECS web application/g' $ git add . $ git commit -m "change message" $ git push origin master
CodePipeline によるデリバリが開始されます。
Docker イメージ作ったり、Docker リポジトリにイメージをプッシュしたりするので少々時間かかります。
動作確認
デプロイ前のページはこんな感じです。
デプロイ完了したらメッセージが変わりました。
自動デプロイできましたね!
まとめ
いかがでしたでしょうか? Docker の継続的デリバリは難しいイメージがありますが、ECS + CodePipeline で非常に簡単に継続的デリバリを実現できました!